var assert      =   require("assert");
var Configure   =   require("../util/config-parser");
var ObjectProxy =   require("./objectProxy");

var Communicator    =   function() {
    this._workers       =   {};
    this._configure     =   undefined;
    this._initialized   =   false;
    this._masterName    =   "";
    this._property      =   {};
}

module.exports  =   Communicator;

Communicator.prototype.__defineGetter__("configure", function() { return this._configure; })
Communicator.prototype.__defineGetter__("masterName", function() { return this._masterName; })

Communicator.New    =   function() {
    return new Communicator();
}

Communicator.prototype.ClientConfig = {
    ModuleName  : "NO_MODULE_NAME",
    LocalIp     : ""
};

Communicator.prototype.setProperty = function (key, value) { this._property[key] = $value; };
Communicator.prototype.getProperty = function (key, value) { return this._property[key] ? this._property[key] : value; };

Communicator.prototype.initialize = function(sFilePath) {
    if(this._initialized || (sFilePath === undefined)) {
        return;
    }
    this._initialized   =   true;
    this._configure =   new Configure();
    this._configure.parseFile(sFilePath);

    this.ClientConfig.ModuleName  = this._configure.get("application.client.modulename", "NO_MODULE_NAME");
    this.ClientConfig.LocalIp     = this._configure.get("application.server.localip", "");
    this._masterName              = this.ClientConfig.ModuleName;

    this.getProperty("timeout") || this.setProperty("timeout",     this._configure.get("application.client.async-invoke-timeout", 30000));   //设置请求调用超时时间，默认为30s
}

Communicator.prototype.stringToProxy    =   function(ProxyHandle, ObjName) {
    assert(ObjName != undefined, "please specify the parameter value for objName");
    assert(ObjName.valueOf("@") != -1, "please specify the parameter value for registry locator");

    ObjName = ObjName.replace(/^[\s\t ]+|[\s\t ]+$/g, '');
    ObjName = ObjName.replace(/\s{2,}/g, ' ');

    var proxy   =   new ProxyHandle();
    proxy._name =   ObjName;
    proxy._worker   =   this._createObjectProxy(ObjName);
    proxy._rpc      =   this._createRPC(proxy);

    return proxy;
}

Communicator.prototype.destroy  =   function() {
    for(var key in this._workers) {
        this._workers[key].destroy();
        delete this._workers[key];
    }
}

Communicator.prototype._createObjectProxy = function(ObjectName, options) {
    if(this._workers.hasOwnProperty(ObjectName)) {
        return this._workers[ObjectName];
    }
    var worker = new ObjectProxy();
    worker.communicator = this;
    var timeout = this.getProperty("timeout");
    if(timeout) {
        worker.timeout = timeout;
    }
    worker.initialize(ObjectName, options);
    this._workers[ObjectName] = worker;

    return worker;
}

Communicator.prototype._createRPC   =   function(Handle) {
    return {
        createFunc : function(funcName) {
            this[funcName] = function() {
                var argsLen =   arguments.length;
                var args    =   new Array(argsLen);
                for(var i = 0; i < argsLen; i++) {
                    args[i] = arguments[i];
                }

                return Handle.rpc_call.apply(Handle, Array.prototype.concat.apply([Handle._worker.genRequestId(), funcName], args));
            }

            return this[funcName];
        }
    };
}
